package dynamic.routing.config;

import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.orm.jpa.EntityManagerFactoryBuilderCustomizer;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.persistenceunit.PersistenceUnitManager;
import org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.persistence.EntityManager;
import javax.sql.DataSource;
import java.util.Map;

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "entityManagerFactoryH2",
        transactionManagerRef = "transactionManagerH2",
        basePackages = {"dynamic.routing.dao.h2"}//Dao层的位置
)
public class H2Config {
    @Autowired
    @Qualifier("h2DataSource")
    private DataSource primaryDataSource;

    @Autowired
    @Qualifier("h2VendorProperties")
    private Map<String, Object> vendorProperties;

    @Bean(name = "entityManagerFactoryBuilderH2")
    public EntityManagerFactoryBuilder entityManagerFactoryBuilder(JpaVendorAdapter jpaVendorAdapter,
                                                                   ObjectProvider<PersistenceUnitManager> persistenceUnitManager,
                                                                   ObjectProvider<EntityManagerFactoryBuilderCustomizer> customizers,
                                                                   @Qualifier("h2JpaProperties") JpaProperties properties) {

        AbstractJpaVendorAdapter abstractJpaVendorAdapter= (AbstractJpaVendorAdapter) jpaVendorAdapter;
        abstractJpaVendorAdapter.setDatabasePlatform("org.hibernate.dialect.H2Dialect");
        abstractJpaVendorAdapter.setDatabase(Database.H2);

        EntityManagerFactoryBuilder builder = new EntityManagerFactoryBuilder(jpaVendorAdapter, properties.getProperties(), (PersistenceUnitManager)persistenceUnitManager.getIfAvailable());
        customizers.orderedStream().forEach((customizer) -> {
            customizer.customize(builder);
        });
        return builder;
    }

    @Bean(name = "entityManagerFactoryH2")
    @Primary
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryH2(@Qualifier("entityManagerFactoryBuilderH2") EntityManagerFactoryBuilder builder){
        return builder
                .dataSource(primaryDataSource)
                .properties(vendorProperties)
                .packages("dynamic.routing.entity.h2")//实体类的位置
                .persistenceUnit("primaryPersistenceUnit")
                .build();
    }

    @Bean(name = "entityManagerH2")
    @Primary
    public EntityManager entityManager(@Qualifier("entityManagerFactoryBuilderH2")EntityManagerFactoryBuilder builder){
        return entityManagerFactoryH2(builder).getObject().createEntityManager();
    }

    @Bean(name = "transactionManagerH2")
    @Primary
    PlatformTransactionManager transactionManagerPrimary(@Qualifier("entityManagerFactoryBuilderH2")EntityManagerFactoryBuilder builder){
        return new JpaTransactionManager(entityManagerFactoryH2(builder).getObject());
    }

}
